﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Gmantis.Controls.Extended
{
    public class ColorPalette : IEnumerable<ColorPaletteEntry>, IEnumerable
    {
        // Fields
        private static Dictionary<Office2007ColorTheme, ColorPalette> _builtIns;
        private List<ColorPaletteEntry> _entries = new List<ColorPaletteEntry>();
        private string _themeName;

        // Methods
        public ColorPalette(string themeName)
        {
            this._themeName = themeName;
        }

        public void Add(Color color)
        {
            this._entries.Add(new ColorPaletteEntry(color));
        }

        public void Add(Color color, string colorName)
        {
            this._entries.Add(new ColorPaletteEntry(color, colorName));
        }

        public void Add(Color color, string colorName, string description)
        {
            this._entries.Add(new ColorPaletteEntry(color, colorName, description));
        }

        private static void BuildThemeTable()
        {
            _builtIns = new Dictionary<Office2007ColorTheme, ColorPalette>();
            ColorPalette palette = new ColorPalette("Standard");
            _builtIns[Office2007ColorTheme.Standard] = palette;
            palette.Add(Rgb(0xc00000), "Dark Red");
            palette.Add(Rgb(0xff0000), "Red");
            palette.Add(Rgb(0xffc000), "Orange");
            palette.Add(Rgb(0xffff00), "Yellow");
            palette.Add(Rgb(0x92d050), "Light Green");
            palette.Add(Rgb(0xb050), "Green");
            palette.Add(Rgb(0xb0f0), "Light Blue");
            palette.Add(Rgb(0x70c0), "Blue");
            palette.Add(Rgb(0x2060), "Dark Blue");
            palette.Add(Rgb(0x7030a0), "Purple");
            palette = new ColorPalette("Highlight");
            _builtIns[Office2007ColorTheme.Highlight] = palette;
            palette.Add(Rgb(0xffff00), "Yellow");
            palette.Add(Rgb(0xff00), "Bright Green");
            palette.Add(Rgb(0xff00ff), "Pink");
            palette.Add(Rgb(0xff), "Blue");
            palette.Add(Rgb(0xff0000), "Red");
            palette.Add(Rgb(0x8080), "Teal");
            palette.Add(Rgb(0x8000), "Green");
            palette.Add(Rgb(0x800080), "Violet");
            palette.Add(Rgb(0x808080), "Gray-50%");
            palette.Add(Rgb(0), "Black");
            palette = new ColorPalette("Office");
            _builtIns[Office2007ColorTheme.Office] = palette;
            palette.Add(Rgb(0xffffff), "White", "Background 1");
            palette.Add(Rgb(0), "Black", "Text 1");
            palette.Add(Rgb(0xeeece1), "Tan", "Background 2");
            palette.Add(Rgb(0x1f497d), "Dark Blue", "Text 2");
            palette.Add(Rgb(0x4f81bd), "Blue", "Accent 1");
            palette.Add(Rgb(0xc0504d), "Red", "Accent 2");
            palette.Add(Rgb(0x9bbb59), "Olive Green", "Accent 3");
            palette.Add(Rgb(0x8064a2), "Purple", "Accent 4");
            palette.Add(Rgb(0x4bacc6), "Aqua", "Accent 5");
            palette.Add(Rgb(0xf79646), "Orange", "Accent 6");
            palette = palette.Clone("GrayScale");
            _builtIns[Office2007ColorTheme.GrayScale] = palette;
            palette.Set(2, Rgb(0xf8f8f8), "White");
            palette.Set(3, Rgb(0), "Black");
            palette.Set(4, Rgb(0xdddddd), "Gray-25%");
            palette.Set(5, Rgb(0xb2b2b2), "Gray-25%");
            palette.Set(6, Rgb(0x969696), "Gray-50%");
            palette.Set(7, Rgb(0x808080), "Gray-50%");
            palette.Set(8, Rgb(0x5f5f5f), "Gray-80%");
            palette.Set(9, Rgb(0x4d4d4d), "Gray-80%");
            palette = palette.Clone("Apex");
            _builtIns[Office2007ColorTheme.Apex] = palette;
            palette.Set(2, Rgb(0xc9c2d1), "Lavender");
            palette.Set(3, Rgb(0x69676d), "Gray-50%");
            palette.Set(4, Rgb(0xceb966), "Tan");
            palette.Set(5, Rgb(0x9cb084), "Olive Green");
            palette.Set(6, Rgb(0x6bb1c9), "Aqua");
            palette.Set(7, Rgb(0x6585cf), "Blue");
            palette.Set(8, Rgb(0x7e6bc9), "Lavender");
            palette.Set(9, Rgb(0xa379bb), "Lavender");
            palette = palette.Clone("Aspect");
            _builtIns[Office2007ColorTheme.Aspect] = palette;
            palette.Set(2, Rgb(0xe3ded1), "Tan");
            palette.Set(3, Rgb(0x323232), "Gray-80%");
            palette.Set(4, Rgb(0xf07f09), "Orange");
            palette.Set(5, Rgb(0x9f2936), "Red");
            palette.Set(6, Rgb(0x1b587c), "Dark Blue");
            palette.Set(7, Rgb(0x4e8542), "Dark Green");
            palette.Set(8, Rgb(0x604878), "Dark Purple");
            palette.Set(9, Rgb(0xc19859), "Tan");
            palette = palette.Clone("Civic");
            _builtIns[Office2007ColorTheme.Civic] = palette;
            palette.Set(2, Rgb(0xc5d1d7), "Ice Blue");
            palette.Set(3, Rgb(0x646b86), "Blue-Gray");
            palette.Set(4, Rgb(0xd16349), "Red");
            palette.Set(5, Rgb(0xccb400), "Dark Yellow");
            palette.Set(6, Rgb(0x8cadae), "Teal");
            palette.Set(7, Rgb(0x8c7b70), "Brown");
            palette.Set(8, Rgb(0x8fb08c), "Green");
            palette.Set(9, Rgb(0xd19049), "Orange");
            palette = palette.Clone("Concourse");
            _builtIns[Office2007ColorTheme.Concourse] = palette;
            palette.Set(2, Rgb(0xdef5fa), "Light Turquoise");
            palette.Set(3, Rgb(0x464646), "Gray-80%");
            palette.Set(4, Rgb(0x2da2bf), "Turquoise");
            palette.Set(5, Rgb(0xda1f28), "Red");
            palette.Set(6, Rgb(0xeb641b), "Orange");
            palette.Set(7, Rgb(0x39639d), "Blue");
            palette.Set(8, Rgb(0x474b78), "Indigo");
            palette.Set(9, Rgb(0x7d3c4a), "Dark Red");
            palette = palette.Clone("Equity");
            _builtIns[Office2007ColorTheme.Equity] = palette;
            palette.Set(2, Rgb(0xe9e5dc), "Tan");
            palette.Set(3, Rgb(0x696464), "Gray-50%");
            palette.Set(4, Rgb(0xd34817), "Orange");
            palette.Set(5, Rgb(0x9b2d1f), "Dark Red");
            palette.Set(6, Rgb(0xa28e6a), "Brown");
            palette.Set(7, Rgb(0x956251), "Brown");
            palette.Set(8, Rgb(0x918485), "Gray-50%");
            palette.Set(9, Rgb(0x855d5d), "Brown");
            palette = palette.Clone("Flow");
            _builtIns[Office2007ColorTheme.Flow] = palette;
            palette.Set(2, Rgb(0xdbf5f9), "Light Turquoise");
            palette.Set(3, Rgb(0x4617b), "Dark Teal");
            palette.Set(4, Rgb(0xf6fc6), "Blue");
            palette.Set(5, Rgb(0x9dd9), "Turquoise");
            palette.Set(6, Rgb(0xbd0d9), "Turquoise");
            palette.Set(7, Rgb(0x10cf9b), "Bright Green");
            palette.Set(8, Rgb(0x7cca62), "Green");
            palette.Set(9, Rgb(0xa5c249), "Lime");
            palette = palette.Clone("Foundry");
            _builtIns[Office2007ColorTheme.Foundry] = palette;
            palette.Set(2, Rgb(0xeaebde), "Tan");
            palette.Set(3, Rgb(0x676a55), "Olive Green");
            palette.Set(4, Rgb(0x72a376), "Green");
            palette.Set(5, Rgb(0xb0ccb0), "Light Green");
            palette.Set(6, Rgb(0xa8cdd7), "Sky Blue");
            palette.Set(7, Rgb(0xc0beaf), "Tan");
            palette.Set(8, Rgb(0xcec597), "Tan");
            palette.Set(9, Rgb(0xe8b7b7), "Rose");
            palette = palette.Clone("Median");
            _builtIns[Office2007ColorTheme.Median] = palette;
            palette.Set(2, Rgb(0xebddc3), "Tan");
            palette.Set(3, Rgb(0x775f55), "Brown");
            palette.Set(4, Rgb(0x94b6d2), "Ice Blue");
            palette.Set(5, Rgb(0xdd8047), "Orange");
            palette.Set(6, Rgb(0xa5ab81), "Olive Green");
            palette.Set(7, Rgb(0xd8b25c), "Gold");
            palette.Set(8, Rgb(0x7ba79d), "Green");
            palette.Set(9, Rgb(0x968c8c), "Gray-50%");
            palette = palette.Clone("Metro");
            _builtIns[Office2007ColorTheme.Metro] = palette;
            palette.Set(2, Rgb(0xd6ecff), "Light Blue");
            palette.Set(3, Rgb(0x4e5b6f), "Blue-Gray");
            palette.Set(4, Rgb(0x7fd13b), "Green");
            palette.Set(5, Rgb(0xea157a), "Pink");
            palette.Set(6, Rgb(0xfeb80a), "Gold");
            palette.Set(7, Rgb(0xaddc), "Turquoise");
            palette.Set(8, Rgb(0x738ac8), "Periwinkle");
            palette.Set(9, Rgb(0x1ab39f), "Teal");
            palette = palette.Clone("Module");
            _builtIns[Office2007ColorTheme.Module] = palette;
            palette.Set(2, Rgb(0xd4d4d6), "Gray-25%");
            palette.Set(3, Rgb(0x5a6378), "Blue-Gray");
            palette.Set(4, Rgb(0xf0ad00), "Gold");
            palette.Set(5, Rgb(0x60b5cc), "Aqua");
            palette.Set(6, Rgb(0xe66c7d), "Rose");
            palette.Set(7, Rgb(0x6bb76d), "Green");
            palette.Set(8, Rgb(0xe88651), "Orange");
            palette.Set(9, Rgb(0xc64847), "Red");
            palette = palette.Clone("Opulent");
            _builtIns[Office2007ColorTheme.Opulent] = palette;
            palette.Set(2, Rgb(0xf4e7ed), "Lavender");
            palette.Set(3, Rgb(0xb13f9a), "Pink");
            palette.Set(4, Rgb(0xb83d68), "Pink");
            palette.Set(5, Rgb(0xac66bb), "Purple");
            palette.Set(6, Rgb(0xde6c36), "Orange");
            palette.Set(7, Rgb(0xf9b639), "Gold");
            palette.Set(8, Rgb(0xcf6da4), "Pink");
            palette.Set(9, Rgb(0xfa8d3d), "Orange");
            palette = palette.Clone("Oriel");
            _builtIns[Office2007ColorTheme.Oriel] = palette;
            palette.Set(2, Rgb(0xfff39d), "Light Yellow");
            palette.Set(3, Rgb(0x575f6d), "Blue-Gray");
            palette.Set(4, Rgb(0xfe8637), "Orange");
            palette.Set(5, Rgb(0x7598d9), "Blue");
            palette.Set(6, Rgb(0xb32c16), "Red");
            palette.Set(7, Rgb(0xf5cd2d), "Gold");
            palette.Set(8, Rgb(0xaebad5), "Ice Blue");
            palette.Set(9, Rgb(0x777c84), "Gray-50%");
            palette = palette.Clone("Origin");
            _builtIns[Office2007ColorTheme.Origin] = palette;
            palette.Set(2, Rgb(0xdde9ec), "Ice Blue");
            palette.Set(3, Rgb(0x464653), "Indigo");
            palette.Set(4, Rgb(0x727ca3), "Blue-Gray");
            palette.Set(5, Rgb(0x9fb8cd), "Ice Blue");
            palette.Set(6, Rgb(0xd2da7a), "Lime");
            palette.Set(7, Rgb(0xfada7a), "Light Yellow");
            palette.Set(8, Rgb(0xb88472), "Brown");
            palette.Set(9, Rgb(0x8e736a), "Brown");
            palette = palette.Clone("Paper");
            _builtIns[Office2007ColorTheme.Paper] = palette;
            palette.Set(2, Rgb(0xfefac9), "Light Yellow");
            palette.Set(3, Rgb(0x444d26), "Dark Green");
            palette.Set(4, Rgb(0xa5b592), "Olive Green");
            palette.Set(5, Rgb(0xf3a447), "Orange");
            palette.Set(6, Rgb(0xe7bc29), "Gold");
            palette.Set(7, Rgb(0xd092a7), "Lavender");
            palette.Set(8, Rgb(0x9c85c0), "Lavender");
            palette.Set(9, Rgb(0x809ec2), "Blue-Gray");
            palette = palette.Clone("Solstice");
            _builtIns[Office2007ColorTheme.Solstice] = palette;
            palette.Set(2, Rgb(0xe7dec9), "Tan");
            palette.Set(3, Rgb(0x4f271c), "Brown");
            palette.Set(4, Rgb(0x3891a7), "Aqua");
            palette.Set(5, Rgb(0xfeb80a), "Gold");
            palette.Set(6, Rgb(0xc32d2e), "Red");
            palette.Set(7, Rgb(0x84aa33), "Green");
            palette.Set(8, Rgb(0x964305), "Brown");
            palette.Set(9, Rgb(0x475a8d), "Indigo");
            palette = palette.Clone("Technic");
            _builtIns[Office2007ColorTheme.Technic] = palette;
            palette.Set(2, Rgb(0xd4d2d0), "Gray-25%");
            palette.Set(3, Rgb(0x3b3b3b), "Gray-80%");
            palette.Set(4, Rgb(0x6ea0b0), "Aqua");
            palette.Set(5, Rgb(0xccaf0a), "Gold");
            palette.Set(6, Rgb(0x8d89a4), "Lavender");
            palette.Set(7, Rgb(0x748560), "Olive Green");
            palette.Set(8, Rgb(0x9e9273), "Brown");
            palette.Set(9, Rgb(0x7e848d), "Gray-50%");
            palette = palette.Clone("Trek");
            _builtIns[Office2007ColorTheme.Trek] = palette;
            palette.Set(2, Rgb(0xfbeec9), "Light Yellow");
            palette.Set(3, Rgb(0x4e3b30), "Brown");
            palette.Set(4, Rgb(0xf0a22e), "Orange");
            palette.Set(5, Rgb(0xa5644e), "Brown");
            palette.Set(6, Rgb(0xb58b80), "Brown");
            palette.Set(7, Rgb(0xc3986d), "Brown");
            palette.Set(8, Rgb(0xa19574), "Brown");
            palette.Set(9, Rgb(0xc17529), "Orange");
            palette = palette.Clone("Urban");
            _builtIns[Office2007ColorTheme.Urban] = palette;
            palette.Set(2, Rgb(0xdedede), "Gray-25%");
            palette.Set(3, Rgb(0x424456), "Blue-Gray");
            palette.Set(4, Rgb(0x53548a), "Indigo");
            palette.Set(5, Rgb(0x438086), "Teal");
            palette.Set(6, Rgb(0xa04da3), "Purple");
            palette.Set(7, Rgb(0xc4652d), "Orange");
            palette.Set(8, Rgb(0x8b5d3d), "Brown");
            palette.Set(9, Rgb(0x5c92b5), "Blue-Gray");
            palette = palette.Clone("Verve");
            _builtIns[Office2007ColorTheme.Verve] = palette;
            palette.Set(2, Rgb(0xd2d2d2), "Gray-25%");
            palette.Set(3, Rgb(0x666666), "Gray-50%");
            palette.Set(4, Rgb(0xff388c), "Pink");
            palette.Set(5, Rgb(0xe40059), "Pink");
            palette.Set(6, Rgb(0x9c007f), "Plum");
            palette.Set(7, Rgb(0x68007f), "Dark Purple");
            palette.Set(8, Rgb(0x5bd3), "Blue");
            palette.Set(9, Rgb(0x349e), "Dark Blue");
        }

        public void Clear()
        {
            this._entries.Clear();
        }

        public ColorPalette Clone(string themeName)
        {
            ColorPalette palette = new ColorPalette(themeName);
            foreach (ColorPaletteEntry entry in this._entries)
            {
                palette._entries.Add(new ColorPaletteEntry(entry.Color, entry.ColorName, entry.Description));
            }
            return palette;
        }

        public bool Contains(Color color)
        {
            for (int i = 0; i < this._entries.Count; i++)
            {
                if (this._entries[i].Color.Equals(color))
                {
                    return true;
                }
            }
            return false;
        }

        public static ColorPalette GetColorPalette(Office2007ColorTheme colorPalette)
        {
            if (_builtIns == null)
            {
                BuildThemeTable();
            }
            return _builtIns[colorPalette];
        }

        public int IndexOf(Color color)
        {
            for (int i = 0; i < this._entries.Count; i++)
            {
                if (this._entries[i].Color.Equals(color))
                {
                    return i;
                }
            }
            return -1;
        }

        private static Color Rgb(int rgb)
        {
            byte r = (byte)((rgb & 0xff0000) >> 0x10);
            byte g = (byte)((rgb & 0xff00) >> 8);
            byte b = (byte)(rgb & 0xff);
            return Color.FromArgb(0xff, r, g, b);
        }

        public void Set(int index, Color color)
        {
            this._entries[index].SetColor(color);
        }

        public void Set(int index, Color color, string colorName)
        {
            this._entries[index].SetColor(color, colorName);
        }

        IEnumerator<ColorPaletteEntry> IEnumerable<ColorPaletteEntry>.GetEnumerator()
        {
            return this._entries.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this._entries.GetEnumerator();
        }

        // Properties
        public int Count
        {
            get
            {
                return this._entries.Count;
            }
        }

        public ColorPaletteEntry this[int index]
        {
            get
            {
                return this._entries[index];
            }
        }

        public string ThemeName
        {
            get
            {
                return this._themeName;
            }
            set
            {
                this._themeName = value;
            }
        }
    }
}
